package com.graduation.file.controller;

import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.StrUtil;
import com.graduation.common.exceptions.BizException;
import com.graduation.common.utils.UserContext;
import com.graduation.file.config.MinioProperties;
import com.graduation.file.utils.MinIOUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Slf4j
@RestController
@RequestMapping("/file")
@RequiredArgsConstructor
public class FileController {

    private final MinioProperties minioProperties;

    // 支持的文档文件类型
    private static final List<String> DOCUMENT_EXTENSIONS = Arrays.asList(".pdf", ".doc", ".docx");

    /**
     * 图片上传接口，返回图片的地址
     */
    @PostMapping("uploadFace/{prefix}")
    public String uploadFile(@PathVariable("prefix") String prefix, MultipartFile file) {
        // 校验文件
        if (file == null) {
            throw new BizException("文件为空");
        }

        // 生成并拼接文件名
        String fileName = UUID.fastUUID().toString(true);
        String originalFilename = file.getOriginalFilename();
        if (StrUtil.isBlank(originalFilename)) {
            throw new BizException("文件错误");
        }
        Long userId = UserContext.getUser();
        String fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
        fileName = StrUtil.format("{}/{}/{}{}", prefix, userId, fileName, fileExtension);

        // 上传文件
        try {
            MinIOUtils.uploadFile(
                    minioProperties.getBucketName(),
                    fileName,
                    file.getInputStream()
            );
        } catch (Exception e) {
            throw new BizException("文件上传错误");
        }

        // 拼接文件路径
        String url = minioProperties.getFileHost() +
                '/' +
                minioProperties.getBucketName() +
                '/' +
                fileName;

        log.info("文件url: {}", url);

        // 返回地址
        return url;
    }

    /**
     * 上传文档文件（PDF、Word等），返回文件信息
     */
    @PostMapping("/uploadDocument")
    public Map<String, String> uploadDocument(MultipartFile file) {
        // 校验文件
        if (file == null) {
            throw new BizException("文件为空");
        }

        String originalFilename = file.getOriginalFilename();
        if (StrUtil.isBlank(originalFilename)) {
            throw new BizException("文件名错误");
        }

        // 获取文件扩展名
        String fileExtension = originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase();
        
        // 校验文件类型
        if (!DOCUMENT_EXTENSIONS.contains(fileExtension)) {
            throw new BizException("仅支持上传PDF、Word文档，当前文件类型：" + fileExtension);
        }

        // 校验文件大小（限制50MB）
        long maxSize = 50 * 1024 * 1024;
        if (file.getSize() > maxSize) {
            throw new BizException("文件大小不能超过50MB");
        }

        // 生成文件名
        Long userId = UserContext.getUser();
        String fileName = UUID.fastUUID().toString(true);
        String objectName = StrUtil.format("documents/{}/{}{}", userId, fileName, fileExtension);

        // 上传文件
        try {
            MinIOUtils.uploadFile(
                    minioProperties.getBucketName(),
                    objectName,
                    file.getInputStream()
            );
        } catch (Exception e) {
            log.error("文件上传失败", e);
            throw new BizException("文件上传失败");
        }

        // 拼接文件路径
        String url = minioProperties.getFileHost() +
                '/' +
                minioProperties.getBucketName() +
                '/' +
                objectName;

        log.info("文档上传成功 - 原始文件名: {}, 存储路径: {}, URL: {}", originalFilename, objectName, url);

        // 返回文件信息
        Map<String, String> result = new HashMap<>();
        result.put("url", url);
        result.put("fileName", originalFilename);
        result.put("objectName", objectName);
        result.put("fileType", fileExtension.substring(1));
        
        return result;
    }

    /**
     * 获取文档预览URL（预签名URL，有效期7天）
     */
    @GetMapping("/previewUrl")
    public Map<String, String> getPreviewUrl(@RequestParam("objectName") String objectName) {
        if (StrUtil.isBlank(objectName)) {
            throw new BizException("文件路径不能为空");
        }

        try {
            // 获取文件扩展名
            String fileExtension = objectName.substring(objectName.lastIndexOf(".")).toLowerCase();
            String fileName = objectName.substring(objectName.lastIndexOf("/") + 1);
            
            // 7天有效期
            int expires = 7 * 24 * 60 * 60;
            String previewUrl;
            String fileType;
            boolean canPreview;

            // 根据文件类型设置不同的预览方式
            if (".pdf".equals(fileExtension)) {
                // PDF文件：浏览器内预览，设置 Content-Disposition: inline
                String contentDisposition = "inline";
                previewUrl = MinIOUtils.getPresignedObjectUrlWithHeaders(
                        minioProperties.getBucketName(),
                        objectName,
                        expires,
                        "application/pdf",
                        contentDisposition
                );
                fileType = "pdf";
                canPreview = true;
            } else if (".doc".equals(fileExtension) || ".docx".equals(fileExtension)) {
                // Word文件：返回普通URL，前端使用Office Online Viewer
                previewUrl = MinIOUtils.getPresignedObjectUrl(
                        minioProperties.getBucketName(),
                        objectName,
                        expires
                );
                fileType = fileExtension.substring(1); // doc 或 docx
                canPreview = false; // 需要第三方预览服务
            } else {
                // 其他文件类型
                previewUrl = MinIOUtils.getPresignedObjectUrl(
                        minioProperties.getBucketName(),
                        objectName,
                        expires
                );
                fileType = fileExtension.substring(1);
                canPreview = false;
            }

            log.info("生成预览URL - 文件: {}, 类型: {}, 可预览: {}", objectName, fileType, canPreview);

            Map<String, String> result = new HashMap<>();
            result.put("previewUrl", previewUrl);
            result.put("objectName", objectName);
            result.put("fileName", fileName);
            result.put("fileType", fileType);
            result.put("canPreview", String.valueOf(canPreview));
            if (!canPreview && (fileType.equals("doc") || fileType.equals("docx"))) {
                result.put("tip", "Word文档建议使用Office Online Viewer预览");
            }
            
            return result;
        } catch (Exception e) {
            log.error("获取预览URL失败", e);
            throw new BizException("获取预览URL失败");
        }
    }

}
